/********************************************
* Copyrigt (C) rumi
* Module: View_UartCore.cpp
*********************************************/
#include "View_UartCore.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include <QThread>

UartCore::UartCore() {
    serialPort = new QSerialPort();
    sendThread = nullptr;
    receiveThread = nullptr;
}

UartCore::~UartCore() {
    closeSerialPort();
    if (sendThread) {
        sendThread->quit();
        sendThread->wait();
        delete sendThread;
    }
    if (receiveThread) {
        receiveThread->quit();
        receiveThread->wait();
        delete receiveThread;
    }
    delete serialPort;
}

bool UartCore::openSerialPort(const QString &portName, int baudRate) {
    serialPort->setPortName(portName);
    serialPort->setBaudRate(baudRate);
    serialPort->setDataBits(QSerialPort::Data8);
    serialPort->setParity(QSerialPort::NoParity);
    serialPort->setStopBits(QSerialPort::OneStop);
    serialPort->setFlowControl(QSerialPort::NoFlowControl);

    if (serialPort->open(QIODevice::ReadWrite)) {
        qDebug() << "Succee to open uart";
        
        startReceiveThread();  // start revice thread
        startSendThread();     // start send thread

        return true;
    } else {
        qDebug() << "Fail to open uart:" << serialPort->errorString();
        return false;
    }
}

void UartCore::closeSerialPort() {
    if (serialPort->isOpen()) {
        serialPort->close();
    }
}

void UartCore::startReceiveThread() {
    receiveThread = new QThread();

    QObject::connect(receiveThread, &QThread::started, this, &UartCore::receiveData);
    moveToThread(receiveThread);
    receiveThread->start();
}

void UartCore::startSendThread() {
    sendThread = new QThread();

    QObject::connect(sendThread, &QThread::started, this, &UartCore::sendData);
    moveToThread(sendThread);
    sendThread->start();
}

void UartCore::receiveData() {
    while (serialPort->isOpen()) {
        if (serialPort->canReadLine()) {
            QByteArray data = serialPort->readAll();
            emit dataReceived(data);  // send revice signal
        }
    }
}

void UartCore::sendData() {
    // In actual use, the sending data can be managed through queues or other means
    while (serialPort->isOpen()) {
        QByteArray data = "Hello, UART!";  // You can fetch data from a queue or other means to send it
        QMutexLocker locker(&mutex);
        serialPort->write(data);
        QThread::sleep(1);  
    }
}

bool UartCore::writeData(const QByteArray &data) {
    QMutexLocker locker(&mutex);
    return serialPort->write(data) != -1;
}

QByteArray UartCore::readData() {
    if (serialPort->canReadLine()) {
        return serialPort->readAll();
    }
    return QByteArray();
}



/********************************************
 * End of file
*********************************************/
